﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.ServiceProcess;
using System.Threading;
using Matrix.Common.Utility;
using Matrix.MaKaYunShang.BLL;
using Matrix.MaKaYunShang.BLL.WxInterfaceFunc;
using Matrix.MaKaYunShang.Model;
using System.Linq;
using Matrix.MaKaYunShang.Model.MatrixCloudApi;
using Matrix.MaKaYunShang.Model.Wechat;

namespace Matrix.MaKaYunShang.RedService
{
    public partial class RedEnvelopesService : ServiceBase
    {
        private readonly Dictionary<string, string> _sendnumLimitItem = new Dictionary<string, string>();
        private readonly MatrixCloudCenterInterFuncBll _matrixCloudCenterInterFuncBllObj =
            new MatrixCloudCenterInterFuncBll();
        public RedEnvelopesService()
        {
            InitializeComponent();
        }
        protected override void OnStart(string[] args)
        {
            //_topNum = _topNum > 30 ? 30 : _topNum;
            _timer = new System.Timers.Timer
            {
                Interval = IntervalTime * int.Parse(ConfigurationManager.AppSettings["IntervalTime"])
            };
            _timer.Elapsed += new System.Timers.ElapsedEventHandler(RedSend_Elapsed);
            _timer.Enabled = true;
        }
        protected override void OnStop()
        {
            this._timer.Enabled = false;
            _whetherToRun = false;
        }
        /// <summary>
        /// 红包发送  
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void RedSend_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (_whetherToRun == true)
            {
                _fileLog.Info("等待上一个线程结束...");
                return;
            }
            _whetherToRun = true;
            if (DateTime.Now.Hour == 01)
            {
                _sendnumLimitItem.Clear();
            }
            SysConfig sysConfig = SysConfigBLL.Instance.GetModelList().FirstOrDefault();
          
            if (sysConfig == null ) { _fileLog.Info("sysConfig or sysMoney is null"); return; }

            var lsLocalProjectInfo = MatrixCloudProjectInfoBLL.Instance.GetModelList();
            if (lsLocalProjectInfo == null || lsLocalProjectInfo.Count == 0)
            {
                _fileLog.Error(
                    "RedEnvelopesService | RedSend_Elapsed | No MatrixCloudProjectInfo info info in dababase ");
                return;
            }
            List<MxApiWeChatRedEnvelopeTask> weChatRedEnvelopeTaskList;
            foreach (var projectInfo in lsLocalProjectInfo)
            {
                var resultTask = _matrixCloudCenterInterFuncBllObj.GetUnSendRedEnvelopeTask(projectInfo.PjMcId,
                    projectInfo.PjSecret);
                if (!resultTask.Status || resultTask.Data == null || resultTask.Data.Count == 0)
                {
                    _fileLog.Info("暂无可发放红包记录");
                    continue;
                }
                weChatRedEnvelopeTaskList = resultTask.Data;

                var resultWechatInfo = _matrixCloudCenterInterFuncBllObj.GetWechatInfo(projectInfo.PjMcId,
                    projectInfo.PjSecret);
                if (!resultWechatInfo.Status)
                {
                    _fileLog.Error("RedEnvelopesService | RedSend_Elapsed | No Wechat info info " +
                                   resultWechatInfo.Message);
                    continue;
                }

                if (resultWechatInfo.Data == null || string.IsNullOrWhiteSpace(resultWechatInfo.Data.AppId))
                {
                    _fileLog.Error("RedSend_Elapsed|wechatInfo is null!");
                    continue;
                }
                var wechatInfo = resultWechatInfo.Data;

                _fileLog.Info("本次发送红包记录为:" + weChatRedEnvelopeTaskList.Count + "条");
                try
                {
                    foreach (var item in weChatRedEnvelopeTaskList)
                    {
                        if (_sendnumLimitItem.ContainsKey(item.OpenIdToPay))
                        {
                            _fileLog.Info("RedSend_Elapsed|该用户今日领取红包个数超过限制!openid=" + item.OpenIdToPay);
                            continue;
                        }
                        #region 验证基本信息
                        if (item.PaySource == 0 && sysConfig.IsSendRedEnvelopeToDelivery == false)
                        {
                            _fileLog.Info("RedSend_Elapsed|未开通配送人员红包发送!");
                            continue;
                        }
                        if (item.PaySource == 1 && sysConfig.IsSendShareRedEnvolope == false)
                        {
                            _fileLog.Info("RedSend_Elapsed|未开通分享红包发送!");
                            continue;
                        }
                        if (_consumerDic.Keys.Contains(item.Id) && (DateTime.Now - _consumerDic[item.Id]).Minutes < 1)
                        {
                            _fileLog.Info("RedSend_Elapsed|一分钟内同一OpenId不可重复发送红包id" + item.Id + "OpenId:" + item.OpenIdToPay);
                            continue;
                        }

                        var dayRedSendCount = 0;
                        var resultCount = _matrixCloudCenterInterFuncBllObj.GetDayRedSendCount(item.PaySource,
                            projectInfo.PjMcId, projectInfo.PjSecret);
                        if (resultCount.Status)
                        {
                            dayRedSendCount = resultCount.Data;
                        }

                        if (item.PaySource == 1)
                        {
                            if (dayRedSendCount >= sysConfig.DayMaxRedEnvolpoe)
                            {
                                _fileLog.Info("RedSend_Elapsed|今日红包发送数量已满,今日发放条数:" + dayRedSendCount);
                                continue;
                            }
                            if (item.Amount > sysConfig.MinRedEnvolope || item.Amount > sysConfig.MaxRedEnvolope)
                            {
                                item.Amount = sysConfig.MinRedEnvolope;
                            }
                        }
                        else
                        {
                            if (dayRedSendCount >= sysConfig.DayMaxCountShareRedEnvolope)
                            {
                                _fileLog.Info("RedSend_Elapsed|今日分享红包发送数量已满,今日发放条数:" + dayRedSendCount);
                                continue;
                            }
                            if (item.Amount > sysConfig.MinRedEnvolopeOfShare || item.Amount > sysConfig.MaxRedEnvolopeOfShare)
                            {
                                item.Amount = sysConfig.MinRedEnvolopeOfShare;
                            }
                        }
                        #endregion

                        #region 数据组装
                        var payWeiXin = new PayWeiXin
                        {
                            AppId = wechatInfo.AppId,
                            PayKey = wechatInfo.PayKey,
                            MchBillno = StringExtension.TimerRandomNumber(wechatInfo.MchId),
                            MchId = wechatInfo.MchId,
                            SendName = wechatInfo.WeChatName,
                            ReOpenid = item.OpenIdToPay,
                            TotalAmount = Convert.ToInt32(item.Amount) * 100,
                            TotalNum = 1,
                            Wishing = ConfigurationManager.AppSettings["DefaultWishing"],
                            ClientIp = ConfigurationManager.AppSettings["LocalWWWIp"],
                            ActName = wechatInfo.WeChatName + "红包分享",
                            Remark = wechatInfo.WeChatName + "现金红包",
                            CertPath = wechatInfo.CertPath
                        };
                        #endregion
                        var weChatRedEnvelopeResult = SendEnvelopeToWeiXin(payWeiXin);//调用支付接口
                        if (weChatRedEnvelopeResult == null)
                        {
                            _fileLog.Info("RedSend_Elapsed|接口调用错误, WeChatRedEnvelopeTask.Id:" + item.Id);
                            continue;
                        }

                        var taskSent = ResultTask(weChatRedEnvelopeResult, item, sysConfig, wechatInfo.Id,
                            item.PaySource, item.OpenIdToPay);

                        var updateResult = _matrixCloudCenterInterFuncBllObj.UpdateRedEnvelopeTaskResult(taskSent,
                            projectInfo.PjMcId, projectInfo.PjSecret);
                        if (!updateResult.Status)
                        {
                            _fileLog.Error("RedEnvelopesService | RedSend_Elapsed | update failed" +
                                           resultWechatInfo.Message + " |  " +  JsonTool.ObjToJson(taskSent));
                            continue;
                        }
                        Thread.Sleep(5000 * 2);
                    }
                    _whetherToRun = false;
                }
                catch (Exception ee)
                {
                    _whetherToRun = false;
                    _fileLog.Info("err:" + ee.StackTrace + "," + ee.InnerException.Message);
                }
            }
        }

        public MxApiWeChatRedEnvelopeTask ResultTask(WeChatRedEnvelopeResult weChatRedEnvelopeResult,
            MxApiWeChatRedEnvelopeTask item, SysConfig sysConfig, int wechatInfoId, int paySource, string openId)
        {
            _fileLog.Info("Result|中奖时间:" + item.AddTime + "中奖Id:" + item.Id + ",openid:" + item.OpenIdToPay + ",msg" + weChatRedEnvelopeResult.return_msg + "[" + weChatRedEnvelopeResult.Data + "]");
            if (_consumerDic.Keys.Contains(item.Id))
                _consumerDic[item.Id] = DateTime.Now;
            else
            {
                _consumerDic.Add(item.Id, DateTime.Now);
            }
            item.MchBillno = weChatRedEnvelopeResult.mch_billno;
            item.SendResult = weChatRedEnvelopeResult.return_msg;
            item.IsSend = true;
            item.SendListid = weChatRedEnvelopeResult.send_listid;
            if (weChatRedEnvelopeResult.return_code == "SUCCESS" && weChatRedEnvelopeResult.result_code == "SUCCESS")
            {
                item.IsActiveGet = true;
                //if (paySource == 1)
                //{
                //    var cpmsumer = ConsumerBLL.Instance.GetConsumerInfoByOpenId(openId, wechatInfoId);
                //}
                //else
                //{
                //    var mcAccounts = McAccountsBLL.Instance.GetModelByOpenId(openId, wechatInfoId);
                //}
            }
            else
            {
                if (weChatRedEnvelopeResult.err_code == "SENDNUM_LIMIT")//当日发放次数过多,,当天不发该用户
                {
                    if (!_sendnumLimitItem.ContainsKey(openId))
                    {
                        item.IsSend = false;
                        item.IsActiveGet = false;
                        _sendnumLimitItem.Add(openId, openId);
                    }
                }
                //受频率限制,账户余额不足,用户账号异常，被拦截,  可重新发送红包,,,如果是这几种情况未发送成功,,程序可以重新发送这条数据
                else if (weChatRedEnvelopeResult.err_code == "NOTENOUGH" || weChatRedEnvelopeResult.err_code == "SEND_FAILED" || weChatRedEnvelopeResult.err_code == "FREQ_LIMIT" || weChatRedEnvelopeResult.err_code == "FATAL_ERROR")
                {
                    item.IsSend = false;
                    item.IsActiveGet = false;
                }
                else
                {
                    item.IsActiveGet = false;
                }
            }
            item.SendTime = DateTime.Now;
            return item;
        }
        #region  发送红包到微信接口 微信返回数据<>实体
        /// <summary>
        /// 发送红包到微信接口 微信返回数据<>实体
        /// </summary>
        private WeChatRedEnvelopeResult SendEnvelopeToWeiXin(PayWeiXin payWeiXin)
        {
            var postData = WxInterRedSendFunc.DoDataForPayWeiXin(payWeiXin);//调用方法
            try
            {   //获取微信返回的xml
                var strPayResult = WxInterRedSendFunc.PayForWeiXin(postData, payWeiXin);
                WeChatRedEnvelopeResult weChatRedEnvelopeResult = XmlSerializeHelper.Deserialize(typeof(WeChatRedEnvelopeResult),
                strPayResult.Replace("xml", "WeChatRedEnvelopeResult")) as
                WeChatRedEnvelopeResult;
                if (weChatRedEnvelopeResult != null)
                {
                    weChatRedEnvelopeResult.Data = strPayResult.Trim();
                }
                return weChatRedEnvelopeResult;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        #endregion
    }
}
